package com.fly.core.config;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import lombok.extern.slf4j.Slf4j;

/**
 * 
 * 异步线程池配置
 * 
 * @author 00fly
 * @version [版本号, 2023年10月22日]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
@Slf4j
@Configuration
@EnableAsync
public class AsyncThreadPoolConfig implements AsyncConfigurer
{
    @Bean
    ThreadPoolTaskExecutor taskExecutor()
    {
        int processors = Runtime.getRuntime().availableProcessors();
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(Math.max(processors, 5));
        executor.setMaxPoolSize(Math.max(processors, 5) * 2);
        executor.setQueueCapacity(10000);
        executor.setKeepAliveSeconds(60);
        executor.setThreadNamePrefix("asyncTask-");
        
        // ThreadPoolExecutor类有几个内部实现类来处理这类情况：
        // AbortPolicy 丢弃任务，抛运行时异常
        // CallerRunsPolicy 执行任务
        // DiscardPolicy 忽视，什么都不会发生
        // DiscardOldestPolicy 从队列中踢出最先进入队列（最后一个执行）的任务
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
        return executor;
    }
    
    @Override
    public Executor getAsyncExecutor()
    {
        return taskExecutor();
    }
    
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler()
    {
        return (ex, method, params) -> {
            log.info("Exception message - {}", ex.getMessage());
            log.info("Method name - {}", method.getName());
            for (Object param : params)
            {
                log.info("Parameter value - {}", param);
            }
        };
    }
}